#include <stdlib.h>
#include <time.h>
#include <curses.h>
#include <math.h>
#define M_X 80
#define M_Y 22
#define ENM 20

char **terrain;
int **seen;
typedef struct {
	int y;
	int x;
	int hp;
}
_chr;
_chr plyr;
_chr enemy_lst[ENM];
//_chr ***enemy_map;

legal(y,x){
	return y>=0&&y<M_Y&&x>=0&&x<M_X;
}
opaque(y,x){
	return '#'==terrain[y][x];
}
dig_cor(y,x,dir){//FIXME
	int ln=3+rand()%3;
	int dx=0; 
	int dy=0;
	if(opaque(y-1,x))
		for(int ny=y;ny>y-ln;ny--)
			terrain[ny][x]='*';
	else if(opaque(y,x+1))
		for(int nx=x;nx<x+ln;nx++)
			terrain[y][nx]='*';
	else if(opaque(y+1,x))
		for(int ny=y;ny<y+ln;ny++)
			terrain[ny][x]='*';
	else if(opaque(y,x-1))
		for(int nx=x;nx>x-ln;nx--)
			terrain[y][nx]='*';
}
dig_room(y,x,ys,xs) {//FIXME(?)
	int neighbrs=1+rand()%4;
	int empty=1;
	for(int yy=y-1; yy<y+ys+1; yy++)
		for(int xx=x-1; xx<x+xs+1; xx++)
			if(!legal(yy,xx)||'.'==terrain[yy][xx])
				empty=0;
	if(empty){
		for(int yy=y; yy<y+ys; yy++)
			for(int xx=x; xx<x+xs; xx++)
				terrain[yy][xx]='.';
		for(int n=0;n<neighbrs;n++){
			int ny; int nx;
			if(rand()%2){
				ny=rand()%2?y+ys-1:y;
				nx=x+1+rand()%(xs-2);
			}else{
				ny=1+y+rand()%(ys-2);
				nx=rand()%2?x+xs-1:x;
			}
			dig_cor(ny,nx);
		}
	}
}
init_map() {
	terrain=malloc(4*M_Y);
	seen=malloc(4*M_Y);
//	enemy_map=malloc(4*M_Y);
	for(int y=0;y<M_Y;y++) {
		terrain[y]=malloc(1*M_X);
		seen[y]=malloc(4*M_X);
//		enemy_map[y]=malloc(4*M_X);
		for(int x=0;x<M_X;x++) {
			terrain[y][x]='#';
			seen[y][x]=0;
//			enemy_map[y][x]=NULL;
		}
	}
	dig_room(M_Y/2,M_X/2,3+rand()%4,3+rand()%9);
/*	for(int e=0;e<ENM;e++) {//FIXME
		_chr *en=&enemy_lst[e];
		en->y=rand()%M_Y;
		en->x=rand()%M_X;
		enemy_map[en->y][en->x]=en;
	}*/
}
/*init_plyr() {
	plyr.y=0;
	plyr.x=0;
}*/
fov() {//FIXME
	for(int r=1;r<3;r++)
		for(int yd=-1*r;yd<=r;yd++)
			for(int xd=-1*r;xd<=r;xd++){
				int ny=plyr.y+yd;
				int nx=plyr.x+xd;
				if(legal(ny,nx)&&!opaque(ny,nx))
					seen[ny][nx]=1;
			}
}
go_to(y,x) {
	if(legal(y,x)) {
		plyr.y=y;
		plyr.x=x;
		fov();
	}
}
key_in(c) {
	int y=plyr.y;
	int x=plyr.x;
	if(KEY_UP==c)
		go_to(y-1,x);
	if(KEY_DOWN==c)
		go_to(y+1,x);
	if(KEY_LEFT==c)
		go_to(y,x-1);
	if(KEY_RIGHT==c)
		go_to(y,x+1);
	if('q'==c)
		return 0;
	return 1;
}
/*col(c) {
	attron(COLOR_PAIR(c));
}*/
draw_scr() {
	for(int y=0;y<M_Y;y++)
		for(int x=0;x<M_X;x++)
			if(seen[y][x]) {
				mvaddch(y,x,terrain[y][x]|(seen[y][x]==1?A_BLINK:0));
				seen[y][x]=2;
			}
	mvaddch(plyr.y,plyr.x,'@');
}
main() {
	srand(time(0));
	keypad(initscr(),1);
	for(int c=start_color();c<8;c++)
		init_pair(c,c,0);
	init_map();
	//init_plyr();
	mvaddstr(12,34,"Welcome to 01");
	while(key_in(getch())) {
		clear();
		draw_scr();
	}
}
